package controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.Set;
import model.Cliente;
import model.Pedido;
import model.PedidoStatus;
import model.Produto;
import dao.ProdutoDAO;

/**
 * Classe que realiza a conexao do usuario com o DAO (o HashMap de Pedidos) 
 * com metodos de inclusao, atualizacao, exclusao e exibicao.
 * 
 * Como detalhe, para os relatorios, os pedidos nao podem ser alterados, pois eles tem
 * os status como cancelado, ou entregue e etc... isso ja conta.
 * 
 * @author Pedro
 * @author Dayane
 */
public class PedidoController {
	
	/**
	 * Instancia estatica de scanner, para nao ter que instancia-la a todo o momento
	 */
	private static Scanner sc = new Scanner(System.in);
	
	/**
	 * Pedir para usuario inserir uma chave via teclado.
	 * 
	 * @return int
	 */
	public static int askKey(){
		System.out.println("Insira a chave do pedido desejado:");
		
		try{
			int key = sc.nextInt();
			sc.nextLine();
			return key;
		}catch (InputMismatchException e) {
            System.err.println("Valor inserido invalido. Insira um numero inteiro");
            sc.nextLine();
            
            // Usando phoenix exception para resolver esse problema.  
            return PedidoController.askKey();
        }
	}
	
	/**
	 * Metodo para pegar informacoes de um novo pedido para cadastrar no cliente passado.
	 * 
	 * @param Cliente cliente
	 * 
	 * @return Pedido pedido
	 */
	public static Pedido toInclude(HashMap<Integer, Produto> produtoList ,Cliente cliente) {

		Pedido pedido = new Pedido();
		
		Date data = new Date();  
		SimpleDateFormat formatador = new SimpleDateFormat("dd/MM/yyyy");
		pedido.setDataLancamento(formatador.format( data ));
		
		// Status novo
		pedido.setStatus(0);
		
		System.out.println("Escolha os produtos pela chave, ou escreva 0 para fechar o pedido.");
		
		ProdutoController.imprimir(Produto.getProdutoList());
		
		Produto produto;
		System.out.println("Codigo do produto:");
		try{
			int entrada = sc.nextInt();
			sc.nextLine();
			while(entrada != 0){
				produto = ProdutoDAO.loadByKey(produtoList, entrada);
				if(produto!= null){
					
					System.out.println("Insira a quantidade: (apenas numeros)");
					produto.setQtd(sc.nextInt());
					sc.nextLine();
					
					pedido.addProduto(produto);
					System.out.println("Produto incluido com sucesso.");
				}else{
					System.out.println(ProdutoDAO.getMsg());
				}
				
				System.out.println("Escolha os produtos pela chave, ou escreva 0 para fechar o pedido.");
				entrada = sc.nextInt();
				sc.nextLine();
			}
			cliente.addPedido(pedido);
			
			return pedido;
		} catch (InputMismatchException e) {
            System.err.println("Valor inserido invalido. Tente novamente.");
            sc.nextLine();
            
            // Usando phoenix exception para resolver esse problema.
            return PedidoController.toInclude(produtoList, cliente);
        }
	}

	/**
	 * Alterar o status do pedido. Informacoes via teclado.
	 * 
	 * @param cliente
	 * @param pedido
	 * 
	 * @return Pedido pedido
	 */
	public static Pedido toAlterarStatus(Cliente cliente) {
		HashMap<Integer, Pedido> pedidoList = cliente.getPedidoList();
		
		System.out.println("Escolha o pedido pela chave, ou escreva 0 para cancelar");
		
		PedidoController.imprimir(pedidoList, false);
		
		try{
			int pedidoKey = sc.nextInt();
			sc.nextLine();
		
			if(pedidoKey!=0){
				if (pedidoList.containsKey(pedidoKey)) {
					Pedido pedido = pedidoList.get(pedidoKey);
					
					System.out.println("Escolha o status pelo codigo:");
					PedidoStatus.imprimirStatusList();
					
					int statusId = sc.nextInt();
					sc.nextLine();
					if(statusId >=0 && statusId < PedidoStatus.getQuantidade()){
						
						pedido.setStatus(statusId);
						System.out.println("Status do pedido alterado com sucesso.");
						return pedido;
						
					}else{
						System.out.println("Codigo do status invalido.");				
					}
				}else{
					System.out.println("Codigo do pedido invalido.");	
				}
			}else{
				System.out.println("Acao cancelada pelo usuario");
			}
		} catch (InputMismatchException e) {
            System.err.println("Valor inserido invalido. Tente novamente");
            sc.nextLine();
            
            // Usando phoenix exception (método que renasce) para resolver esse problema.
            return PedidoController.toAlterarStatus(cliente);
        }
		
		System.out.println("Pedido nao alterado.");
		return null;
	}
	
	/**
	 * Imprimir todos os clientes na lista passada.
	 * 
	 * @param HashMap<Integer, Pedido> pedidoList
	 */
	public static void imprimir(HashMap<Integer, Pedido> pedidoList, boolean imprimirProdutos) {
		Set<Integer> pedidosKeys = pedidoList.keySet();

		for (int key : pedidosKeys) {
			pedidoList.get(key).imprimir(imprimirProdutos);
		}

	}
	
	/**
	 * Calcular faturamento da lista passada.
	 * 
	 * @param HashMap<Integer, Pedido> pedidoList
	 */
	public static double toFaturamento(HashMap<Integer, Pedido> pedidoList){
		Set<Integer> a = pedidoList.keySet();
		double Vtotal = 0;
		for (int y : a) {
			Vtotal += pedidoList.get(y).getValorTotal();
		}
		return Vtotal;
	}
	
	/**
     * Calcular n�mero de pedidos com status da lista passada.
     * 
     * @param HashMap<Integer, Pedido> pedidoList
     * @param String status
     */
    public static double toStatus(HashMap<Integer, Pedido> pedidoList, String status){
        int total=0;
        
        Set<Integer> a = pedidoList.keySet();
        
        for (int y : a) {
        	if(status.equalsIgnoreCase(""+pedidoList.get(y).getStatus())) total++;
        }
        return total;
    }
}
